"""
Case Type   : 小型化
Case Name   : 大版本基本功能参数，备post升级后回滚流程测试
Create At   : 2024/5/8
Owner       : qumin
Description :
    1.安装旧版本数据库
    2.获取版本version_id
    2.1.获取旧版本version_id
    cat version.cfg | awk 'NR==1'
    2.2.获取新版本version_id
    cat version.cfg | awk 'NR==1'
    3.pre升级
    3.1.主pre升级
    sh upgrade_GAUSSV5.sh -t upgrade_pre -m primary;
    3.2.备pre升级
    sh upgrade_GAUSSV5.sh -t upgrade_pre -m standby;
    4.bin升级
    4.1.主bin升级
    sh upgrade_GAUSSV5.sh -t upgrade_bin -m primary;
    4.2.备bin升级
    sh upgrade_GAUSSV5.sh -t upgrade_bin -m standby;
    5.post升级
    5.1.主post升级
    sh upgrade_GAUSSV5.sh -t upgrade_post -m primary;
    5.2.备post升级
    sh upgrade_GAUSSV5.sh -t rollback_post -m standby;
    5.3.备post回滚
    sh upgrade_GAUSSV5.sh -t rollback_post -m standby;
    5.4.备post升级
    sh upgrade_GAUSSV5.sh -t upgrade_post -m standby;
    6.commit升级
    6.1.主commit升级
    sh upgrade_GAUSSV5.sh -t upgrade_commit -m primary;
    6.2.备commit升级
    sh upgrade_GAUSSV5.sh -t upgrade_commit -m standby;
    7.升级后版本验证
    7.1.主：获取当前版本version_id
    gaussdb -V | cut -d ')' -f1 | awk  '{print $3}'
    7.2.备：获取当前版本version_id
    gaussdb -V | cut -d ')' -f1 | awk  '{print $3}'
    8.清理数据环境
    sh uninstall.sh --delete-data
Expect      :
    1.旧版本数据库安装成功
    2.版本获取成功
    3.pre回滚后再次升级成功
    4.bin升级成功
    5.post升级成功
    6.commit升级成功
    7.升级后版本验证成功
    8.清理完成
History     :
"""

import os
import unittest
import time
from testcase.utils.Common import Common
from testcase.utils.Common import CommonSH
from testcase.utils.Constant import Constant
from testcase.utils.Logger import Logger
from yat.test import Node
from yat.test import macro


class Lite(unittest.TestCase):
    def setUp(self):
        self.log = Logger()
        self.log.info(f'-----{os.path.basename(__file__)} start-----')
        self.pri_root = Node('PrimaryRoot')
        self.pri_node = Node('PrimaryDbUser')
        self.sta_root = Node('Standby1Root')
        self.sta_node = Node('Standby1DbUser')
        self.common = Common()
        self.constant = Constant()
        self.home_path = (os.path.dirname(macro.DB_PKG_PATH))
        self.lpkg_path = os.path.join(self.home_path, 'lpkg_path')
        self.hpkg_path = os.path.join(self.home_path, 'hpkg_path')
        self.install_path = os.path.join(self.home_path, 'install_path')
        self.data_path = os.path.join(self.home_path, 'data_path')
        self.u_name = 'u_mini_0007'
        self.env_path = os.path.join('/home', self.u_name, '.bashrc')
        self.lversion_name = os.path.join(self.lpkg_path, 'version.cfg')
        self.hversion_name = os.path.join(self.hpkg_path, 'version.cfg')

    def test_upgrade(self):
        text = '----查询系统未使用端口----'
        self.log.info(text)
        port = []
        for i in range(3):
            port.append(self.common.get_not_used_port(self.pri_root))
            i = i + 1
        self.log.info(port)

        text = '----创建数据库用户和用户组;expect:创建成功----'
        self.log.info(text)
        test_print = self.pri_root.sh('hostname -I').result()
        self.log.info(test_print)
        self.common.create_user(self.pri_root, self.u_name)
        test_print = self.sta_root.sh('hostname -I').result()
        self.log.info(test_print)
        self.common.create_user(self.sta_root, self.u_name)

        text = '----创建数据，安装包等目录;expect:创建成功----'
        self.log.info(text)
        for d in (self.data_path, self.install_path,
                  self.lpkg_path, self.hpkg_path):
            mkdir_cmd = f'if [ ! -d "{d}" ]; then mkdir -p "{d}"; \
                        echo "创建成功，目录已存在";' \
                        f'else echo "目录已存在无需创建"; rm -rf {d}/*; fi'
            result1 = self.common.get_sh_result(self.pri_root, mkdir_cmd)
            result2 = self.common.get_sh_result(self.sta_root, mkdir_cmd)
            self.assertIn('目录已存在', result1, '执行失败:' + text)
            self.assertIn('目录已存在', result2, '执行失败:' + text)

        text = '----获取数据库安装包 expect:成功----'
        self.log.info(text)
        pri_res = self.common.get_and_tar_pkg(self.pri_root, macro.WGET_PATH,
                  self.lpkg_path, macro.DB_LPKG_FILE)
        sta_res = self.common.get_and_tar_pkg(self.sta_root, macro.WGET_PATH,
                  self.lpkg_path, macro.DB_LPKG_FILE)
        self.assertEqual(len(pri_res.strip()), 0, '执行失败：' + text)
        self.assertEqual(len(sta_res.strip()), 0, '执行失败：' + text)

        text = '----解压小型化低版本安装包 expect:成功----'
        self.log.info(text)
        ls_cmd = f"ls {self.lpkg_path}|grep -E '*Lite.*tar.gz'"
        lfile_name = self.common.get_sh_result(self.pri_root, ls_cmd)
        tar_cmd = f'cd {self.lpkg_path};tar -xf {lfile_name}'
        self.log.info(tar_cmd)
        tar_res1 = self.common.get_sh_result(self.pri_root, tar_cmd)
        tar_res2 = self.common.get_sh_result(self.sta_root, tar_cmd)
        ls_res1 = self.common.get_sh_result(self.pri_root,
                                            f'ls -l {self.lpkg_path}')
        ls_res2 = self.common.get_sh_result(self.sta_root,
                                            f'ls -l {self.lpkg_path}')
        self.assertIn('install.sh', ls_res1, '执行失败:' + text)
        self.assertIn('install.sh', ls_res2, '执行失败:' + text)
        text = '----解压小型化高版本安装包 expect:成功----'
        self.log.info(text)
        ls_cmd = f"ls {macro.DB_PKG_PATH}|grep -E '*Lite.*tar.gz'"
        hfile_name = self.common.get_sh_result(self.pri_root, ls_cmd)
        tar_cmd = f'cd {macro.DB_PKG_PATH};' \
                  f'tar -xf {hfile_name} -C {self.hpkg_path} '
        self.log.info(tar_cmd)
        tar_res1 = self.common.get_sh_result(self.pri_root, tar_cmd)
        tar_res2 = self.common.get_sh_result(self.sta_root, tar_cmd)
        ls_res1 = self.common.get_sh_result(self.pri_root,
                                            f'ls -l {self.hpkg_path}')
        ls_res2 = self.common.get_sh_result(self.sta_root,
                                            f'ls -l {self.hpkg_path}')
        self.assertIn('install.sh', ls_res1, '执行失败:' + text)
        self.assertIn('install.sh', ls_res2, '执行失败:' + text)

        text = '----root用户修改安装包解压目录、安装目录、数据目录的路径权限和属主;expect:修改成功----'
        self.log.info(text)
        file_own = f'chown -R {self.u_name}:{self.u_name} ' \
                   f'{self.install_path} {self.data_path} ' \
                   f'{self.lpkg_path} {self.hpkg_path};'
        self.log.info(file_own)
        file_msg1 = self.common.get_sh_result(self.pri_root, file_own)
        self.log.info(file_msg1)
        file_msg2 = self.common.get_sh_result(self.sta_root, file_own)
        self.log.info(file_msg2)
        self.assertEqual('', file_msg1, '执行失败：' + text)
        self.assertEqual('', file_msg2, '执行失败：' + text)

        chm_cmd = f'chmod -R 755 {self.install_path} {self.data_path} ' \
                  f'{self.lpkg_path} {self.hpkg_path};' \
                  f'chmod 777 {self.home_path};'
        self.log.info(chm_cmd)
        chm_result1 = self.common.get_sh_result(self.pri_root, chm_cmd)
        chm_result2 = self.common.get_sh_result(self.sta_root, chm_cmd)
        self.assertEqual('', chm_result1, '执行失败：' + text)
        self.assertEqual('', chm_result2, '执行失败：' + text)

        text = '----step1:安装旧版本数据库;expect:安装成功----'
        self.log.info(text)
        text = '----step1.1:主节点安装旧版本数据库;expect:安装成功----'
        self.log.info(text)
        install_cmd = f' su - {self.u_name} -c " cd {self.lpkg_path}&&' \
                      f'sh  install.sh --mode primary -D {self.data_path} ' \
                      f'-R {self.install_path} ' \
                      f'-P \\\"-w {macro.COMMON_PASSWD}\\\" ' \
                      f'-C port={port[0]} ' \
                      f'-C \\\"replconninfo1=\'localhost={self.pri_node.db_host}' \
                      f' localport={port[1]} ' \
                      f'remotehost={self.sta_node.db_host} ' \
                      f'remoteport={port[2]}\'\\\" ' \
                      f'--start&& source {self.env_path}"'
        install_msg1 = self.common.get_sh_result(self.pri_root, install_cmd)
        self.assertIn('start datanode success',
                      install_msg1, '执行失败' + text)
        text = '----step1.2:备节点安装旧版本数据库;expect:安装成功----'
        self.log.info(text)
        install_cmd = f' su - {self.u_name} -c " cd {self.lpkg_path}&&' \
                      f'sh  install.sh --mode standby -D {self.data_path} ' \
                      f'-R {self.install_path} ' \
                      f'-P \\\"-w {macro.COMMON_PASSWD}\\\" ' \
                      f'-C port={port[0]} ' \
                      f'-C \\\"replconninfo1=' \
                      f'\'localhost={self.sta_node.db_host}' \
                      f' localport={port[2]} ' \
                      f'remotehost={self.pri_node.db_host} ' \
                      f'remoteport={port[1]}\'\\\" ' \
                      f'--start&& source {self.env_path}"'
        install_msg2 = self.common.get_sh_result(self.sta_root, install_cmd)
        self.assertIn('start datanode success',
                      install_msg2, '执行失败' + text)

        text = '----step2:获取版本version_id;expect:成功----'
        self.log.info(text)
        text = '----step2.1:获取版本低版本version_id;expect:成功----'
        self.log.info(text)
        cat_cmd1 = f'su - {self.u_name} -c "cat {self.lversion_name}| awk \'NR==1\'"'
        cat_msg1 = self.common.get_sh_result(self.pri_root, cat_cmd1)
        lversion = cat_msg1.split("-")[-1]
        self.assertIn('5.0.0', lversion, '执行失败' + text)
        text = '----step2.2:获取版本高版本version_id;expect:成功----'
        self.log.info(text)
        cat_cmd2 = f'su - {self.u_name} -c "cat {self.hversion_name}| awk \'NR==1\'"'
        cat_msg2 = self.common.get_sh_result(self.sta_root, cat_cmd2)
        hversion = cat_msg2.split("-")[-1]
        self.assertNotEquals(lversion, hversion, '执行失败' + text)

        text = '----step3:pre升级;expect:成功----'
        self.log.info(text)
        text = '----step3.1:主pre升级;expect:成功----'
        self.log.info(text)
        su_cmd = f'su - {self.u_name}'
        pre_cmd = f'cd  {self.hpkg_path}&& sh upgrade_GAUSSV5.sh ' \
                  f'-t upgrade_pre -m primary'
        execute_cmd = f'''expect <<EOF
                                spawn {su_cmd}
                                expect "$"
                                send "{pre_cmd}\\n"
                                expect "input sql password:"
                                send "{macro.COMMON_PASSWD}\\n"
                                expect eof\n''' + '''EOF'''
        pre_msg1 = self.common.get_sh_result(self.pri_root, execute_cmd)
        self.assertIn('The upgrade_pre step is executed successfully',
                      pre_msg1, '执行失败' + text)

        text = '----step3.2:备pre升级;expect:成功----'
        self.log.info(text)
        pre_cmd2 = f'su - {self.u_name} -c " ' \
                   f'cd  {self.hpkg_path}&& sh upgrade_GAUSSV5.sh ' \
                   f'-t upgrade_pre -m standby"'
        pre_msg2 = self.common.get_sh_result(self.sta_root, pre_cmd2)
        self.assertIn('The upgrade_pre step is executed successfully',
                      pre_msg2, '执行失败' + text)

        text = '----step4:bin升级;expect:成功----'
        self.log.info(text)
        text = '----step4.1:主bin升级;expect:成功----'
        self.log.info(text)
        bin_cmd1 = f'su - {self.u_name} -c "' \
                   f'cd  {self.hpkg_path}&& sh upgrade_GAUSSV5.sh ' \
                   f'-t upgrade_bin -m primary;"'
        bin_msg1 = self.common.get_sh_result(self.pri_root, bin_cmd1)
        self.log.info(bin_msg1)
        self.assertIn('The upgrade_bin step is executed successfully',
                      bin_msg1, '执行失败' + text)
        text = '----step4.2:备bin升级;expect:成功----'
        self.log.info(text)
        bin_cmd2 = f'su - {self.u_name} -c "' \
                   f'cd  {self.hpkg_path}&& sh upgrade_GAUSSV5.sh ' \
                   f'-t upgrade_bin -m standby;"'
        bin_msg2 = self.common.get_sh_result(self.sta_root, bin_cmd2)
        self.log.info(bin_msg2)
        self.assertIn('The upgrade_bin step is executed successfully',
                      bin_msg2, '执行失败' + text)

        text = '----step5:post升级;expect:成功----'
        self.log.info(text)
        text = '----step5.1:主post升级;expect:成功----'
        self.log.info(text)
        su_cmd = f'su - {self.u_name}'
        post_cmd1 = f'cd  {self.hpkg_path}&& sh upgrade_GAUSSV5.sh ' \
                    f'-t upgrade_post -m primary'
        execute_cmd = f'''expect <<EOF
                                spawn {su_cmd}
                                expect "$"
                                send "{post_cmd1}\\n"
                                expect "input sql password:"
                                send "{macro.COMMON_PASSWD}\\n"
                                expect eof\n''' + '''EOF'''
        post_msg1 = self.common.get_sh_result(self.pri_root, execute_cmd)
        self.assertIn('The upgrade_post step is executed successfully',
                      post_msg1, '执行失败' + text)
        text = '----step5.2:备post升级;expect:成功----'
        self.log.info(text)
        post_cmd2 = f'su - {self.u_name} -c "' \
                    f'cd  {self.hpkg_path}&& sh upgrade_GAUSSV5.sh ' \
                    f'-t upgrade_post -m standby;"'
        post_msg2 = self.common.get_sh_result(self.sta_root, post_cmd2)
        self.log.info(post_msg2)
        self.assertIn('The upgrade_post step is executed successfully',
                      post_msg2, '执行失败' + text)
        text = '----step5.3:备post升级回滚;expect:成功----'
        self.log.info(text)
        su_cmd = f'su - {self.u_name}'
        post_cmd1 = f'cd  {self.hpkg_path}&& sh upgrade_GAUSSV5.sh ' \
                    f'-t rollback_post -m  standby'
        execute_cmd = f'''expect <<EOF
                                        spawn {su_cmd}
                                        expect "$"
                                        send "{post_cmd1}\\n"
                                        expect "input sql password:"
                                        send "{macro.COMMON_PASSWD}\\n"
                                        expect eof\n''' + '''EOF'''
        post_msg1 = self.common.get_sh_result(self.sta_root, execute_cmd)
        self.assertIn('The rollback_post step is executed successfully',
                      post_msg1, '执行失败' + text)
        text = '----step5.4:备post升级;expect:成功----'
        self.log.info(text)
        post_cmd2 = f'su - {self.u_name} -c "' \
                    f'cd  {self.hpkg_path}&& sh upgrade_GAUSSV5.sh ' \
                    f'-t upgrade_post -m standby;"'
        post_msg2 = self.common.get_sh_result(self.sta_root, post_cmd2)
        self.log.info(post_msg2)
        self.assertIn('The upgrade_post step is executed successfully',
                      post_msg2, '执行失败' + text)

        text = '----step6:commit升级;expect:成功----'
        self.log.info(text)
        text = '----step6.1:主commit升级;expect:成功----'
        self.log.info(text)
        commit_cmd1 = f'su - {self.u_name} -c "' \
                      f'cd  {self.hpkg_path}&& sh upgrade_GAUSSV5.sh ' \
                      f'-t upgrade_commit -m primary;"'
        commit_msg1 = self.common.get_sh_result(self.pri_root, commit_cmd1)
        self.log.info(commit_msg1)
        self.assertIn('The upgrade_commit step is executed successfully',
                      commit_msg1, '执行失败' + text)
        text = '----step6.2:备commit升级;expect:成功----'
        self.log.info(text)
        commit_cmd2 = f'su - {self.u_name} -c "' \
                      f'cd  {self.hpkg_path}&& sh upgrade_GAUSSV5.sh ' \
                      f'-t upgrade_commit -m standby;"'
        commit_msg2 = self.common.get_sh_result(self.sta_root, commit_cmd2)
        self.log.info(pre_msg2)
        self.assertIn('The upgrade_commit step is executed successfully',
                      commit_msg2, '执行失败' + text)

        text = '----step7:升级后版本验证;expect:升级成功----'
        self.log.info(text)
        version_cmd = f'''su - {self.u_name} -c "gaussdb -V |cut -d ')' \
        -f1|awk '{{{{print $3}}}}'"'''
        text = '----step7.1:主节点获取当前版本version_id;expect:成功----'
        self.log.info(text)
        version_msg1 = self.common.get_sh_result(self.pri_root,
                                                 version_cmd).lower()
        self.log.info(version_msg1)
        text = '----step7.2:备节点获取当前版本version_id;expect:成功----'
        self.log.info(text)
        version_msg2 = self.common.get_sh_result(self.sta_root,
                                                 version_cmd).lower()
        self.log.info(version_msg2)
        self.assertIn(hversion, version_msg1, '执行失败' + text)
        self.assertIn(hversion, version_msg2, '执行失败' + text)

    def tearDown(self):
        text = '----step8:清理环境;expect:清理环境成功----'
        self.log.info(text)
        uninstall_cmd = f'su - {self.u_name} -c "' \
                        f'source {self.env_path}&&' \
                        f'cd {self.hpkg_path}&&' \
                        f'sh uninstall.sh --delete-data && ' \
                        f'sed -i \'/export/d\' {self.env_path} && ' \
                        f'source {self.env_path}"'
        uninstall_msg1 = self.common.get_sh_result(self.pri_root, uninstall_cmd)
        self.log.info(uninstall_msg1)
        uninstall_msg2 = self.common.get_sh_result(self.sta_root, uninstall_cmd)
        self.log.info(uninstall_msg2)
        rm_cmd = f'rm -rf {self.install_path} {self.data_path} ' \
                 f'{self.hpkg_path} {self.lpkg_path};'
        self.log.info(rm_cmd)
        rm_result1 = self.common.get_sh_result(self.pri_root, rm_cmd)
        self.log.info(rm_result1)
        rm_result2 = self.common.get_sh_result(self.sta_root, rm_cmd)
        self.log.info(rm_result2)
        user_result1 = self.common.del_user(self.pri_root, self.u_name)
        user_result2 = self.common.del_user(self.sta_root, self.u_name)
        self.log.info(user_result1)
        self.log.info(user_result2)
        self.assertIn('clean up related processes success',
                      uninstall_msg1, '执行失败' + text)
        self.assertIn('clean up related processes success',
                      uninstall_msg2, '执行失败' + text)
        self.assertEqual('', rm_result1, '执行失败:' + text)
        self.assertEqual('', rm_result2, '执行失败:' + text)
        self.assertEqual('', user_result1, '删除用户失败:' + text)
        self.assertEqual('', user_result2, '删除用户失败:' + text)
        self.log.info(f'-----{os.path.basename(__file__)} end-----')
